home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 117 / PC Guia 117.iso / Software / Produtividade / Software2 / Product4 / Setup.exe / drupal-4.6.0 / modules / menu.module < prev    next >
Encoding:
Text File  |  2005-03-31  |  16.9 KB  |  506 lines

  1. <?php
  2. // $Id: menu.module,v 1.29 2005/03/31 21:18:08 dries Exp $
  3.  
  4. /**
  5.  * @file
  6.  * Allows administrators to customize the site navigation menu.
  7.  */
  8.  
  9. /**
  10.  * Implementation of hook_menu().
  11.  */
  12. function menu_menu($may_cache) {
  13.   $items = array();
  14.  
  15.   if ($may_cache) {
  16.     $items[] = array('path' => 'admin/menu', 'title' => t('menus'),
  17.       'callback' => 'menu_overview',
  18.       'access' => user_access('administer menu'));
  19.     $items[] = array('path' => 'admin/menu/item/edit', 'title' => t('edit menu item'),
  20.       'callback' => 'menu_edit_item',
  21.       'access' => user_access('administer menu'),
  22.       'type' => MENU_CALLBACK);
  23.     $items[] = array('path' => 'admin/menu/item/reset', 'title' => t('reset menu item'),
  24.       'callback' => 'menu_reset_item',
  25.       'access' => user_access('administer menu'),
  26.       'type' => MENU_CALLBACK);
  27.     $items[] = array('path' => 'admin/menu/item/disable', 'title' => t('disable menu item'),
  28.       'callback' => 'menu_disable_item',
  29.       'access' => user_access('administer menu'),
  30.       'type' => MENU_CALLBACK);
  31.     $items[] = array('path' => 'admin/menu/item/delete', 'title' => t('delete menu item'),
  32.       'callback' => 'menu_delete_item',
  33.       'access' => user_access('administer menu'),
  34.       'type' => MENU_CALLBACK);
  35.  
  36.     $items[] = array('path' => 'admin/menu/list', 'title' => t('list'),
  37.       'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
  38.     $items[] = array('path' => 'admin/menu/menu/add', 'title' => t('add menu'),
  39.       'callback' => 'menu_add_menu',
  40.       'access' => user_access('administer menu'),
  41.       'type' => MENU_LOCAL_TASK);
  42.     $items[] = array('path' => 'admin/menu/item/add', 'title' => t('add menu item'),
  43.       'callback' => 'menu_edit_item',
  44.       'access' => user_access('administer menu'),
  45.       'type' => MENU_LOCAL_TASK);
  46.     $items[] = array('path' => 'admin/menu/reset', 'title' => t('reset menus'),
  47.       'callback' => 'menu_reset',
  48.       'access' => user_access('administer menu'),
  49.       'type' => MENU_LOCAL_TASK);
  50.   }
  51.  
  52.   return $items;
  53. }
  54.  
  55. /**
  56.  * Implementation of hook_help().
  57.  */
  58. function menu_help($section) {
  59.   switch ($section) {
  60.     case 'admin/modules#description':
  61.       return t('Allows administrators to customize the site navigation menu.');
  62.     case 'admin/menu':
  63.       return t('<p>Select an operation from the list to move, change, or delete a menu item.</p>');
  64.     case 'admin/menu/menu/add':
  65.       return t('<p>Enter the name for your new menu. Remember to enable the newly created block in the %blocks administration page.</p>', array('%blocks' => l(t('blocks'), 'admin/block')));
  66.     case 'admin/menu/item/add':
  67.       return t('<p>Enter the title, path, position and the weight for your new menu item.</p>');
  68.   }
  69. }
  70.  
  71. /**
  72.  * Implementation of hook_block().
  73.  */
  74. function menu_block($op = 'list', $delta = 0) {
  75.   $menu = menu_get_menu();
  76.  
  77.   if ($op == 'list') {
  78.     $blocks = array();
  79.     foreach ($menu['items'][0]['children'] as $mid) {
  80.       // Default "Navigation" block is handled by user.module.
  81.       if ($mid != 1) {
  82.         $blocks[$mid]['info'] = $menu['items'][$mid]['title'];
  83.       }
  84.     }
  85.     return $blocks;
  86.   }
  87.   else if ($op == 'view') {
  88.     $data['subject'] = $menu['items'][$delta]['title'];
  89.     $data['content'] = '<div class="menu">'. theme('menu_tree', $delta) .'</div>' ;
  90.     return $data;
  91.   }
  92. }
  93.  
  94. /**
  95.  * Implementation of hook_perm().
  96.  */
  97. function menu_perm() {
  98.   return array('administer menu');
  99. }
  100.  
  101. /**
  102.  * Menu callback; present the main menu management page.
  103.  */
  104. function menu_overview() {
  105.   menu_rebuild();
  106.  
  107.   print theme('page', menu_overview_tree());
  108. }
  109.  
  110. /**
  111.  * Menu callback; clear the database, resetting the menu to factory defaults.
  112.  */
  113. function menu_reset() {
  114.   $op = $_POST['op'];
  115.   switch ($op) {
  116.     case t('Reset all'):
  117.       db_query('DELETE FROM {menu}');
  118.       drupal_set_message(t('All menu items reset.'));
  119.       drupal_goto('admin/menu');
  120.       break;
  121.     default:
  122.       $output = theme('confirm',
  123.                       t('Are you sure you want to reset all menu items to their default settings?'),
  124.                       'admin/menu',
  125.                       t('Any custom additions or changes to the menu will be lost.'),
  126.                       t('Reset all'));
  127.       print theme('page', $output);
  128.   }
  129. }
  130.  
  131. /**
  132.  * Menu callback; handle the adding of a new menu.
  133.  */
  134. function menu_add_menu() {
  135.   $op = $_POST['op'];
  136.   $edit = $_POST['edit'];
  137.   $output = '';
  138.  
  139.   switch ($op) {
  140.     case t('Submit'):
  141.       menu_edit_item_validate($edit);
  142.       if (!form_get_errors()) {
  143.         menu_edit_item_save($edit);
  144.         drupal_goto('admin/menu');
  145.       }
  146.       // Fall through.
  147.     default:
  148.       $edit['pid'] = 0;
  149.       $edit['type'] = MENU_CUSTOM_MENU;
  150.       $output .= menu_edit_item_form($edit);
  151.   }
  152.  
  153.   print theme('page', $output);
  154. }
  155.  
  156. /**
  157.  * Menu callback; reset a single modified item.
  158.  */
  159. function menu_reset_item($mid) {
  160.   $op = $_POST['op'];
  161.   switch ($op) {
  162.     case t('Reset'):
  163.       db_query('DELETE FROM {menu} WHERE mid = %d', $mid);
  164.       drupal_set_message(t('Menu item reset.'));
  165.       drupal_goto('admin/menu');
  166.       break;
  167.     default:
  168.       $title = db_result(db_query('SELECT title FROM {menu} WHERE mid = %d', $mid));
  169.       $output = theme('confirm',
  170.                       t('Are you sure you want to reset the item %item to its default values?', array('%item' => theme('placeholder', $title))),
  171.                       'admin/menu',
  172.                       t('Any customizations will be lost. This action cannot be undone.'),
  173.                       t('Reset'));
  174.       print theme('page', $output);
  175.   }
  176. }
  177.  
  178. /**
  179.  * Menu callback; delete a single custom item.
  180.  */
  181. function menu_delete_item($mid) {
  182.   $op = $_POST['op'];
  183.   $result = db_query('SELECT type, title FROM {menu} WHERE mid = %d', $mid);
  184.   $menu = db_fetch_object($result);
  185.   if (!$menu) {
  186.     drupal_goto('admin/menu');
  187.   }
  188.   switch ($op) {
  189.     case t('Delete'):
  190.       db_query('DELETE FROM {menu} WHERE mid = %d', $mid);
  191.       if ($menu->type & MENU_IS_ROOT) {
  192.         drupal_set_message(t('Menu deleted.'));
  193.       }
  194.       else {
  195.         drupal_set_message(t('Menu item deleted.'));
  196.       }
  197.       drupal_goto('admin/menu');
  198.       break;
  199.     default:
  200.       if ($menu->type & MENU_IS_ROOT) {
  201.         $message = t('Are you sure you want to delete the menu %item?', array('%item' => theme('placeholder', $menu->title)));
  202.       }
  203.       else {
  204.         $message = t('Are you sure you want to delete the custom menu item %item?', array('%item' => theme('placeholder', $menu->title)));
  205.       }
  206.       $output = theme('confirm', $message, 'admin/menu', t('This action cannot be undone.'), t('Delete'));
  207.       print theme('page', $output);
  208.   }
  209. }
  210.  
  211. /**
  212.  * Menu callback; hide a menu item.
  213.  */
  214. function menu_disable_item($mid) {
  215.   $menu = menu_get_menu();
  216.   $type = $menu['items'][$mid]['type'];
  217.   $type &= ~MENU_VISIBLE_IN_TREE;
  218.   $type &= ~MENU_VISIBLE_IN_BREADCRUMB;
  219.   $type |= MENU_MODIFIED_BY_ADMIN;
  220.   db_query('UPDATE {menu} SET type = %d WHERE mid = %d', $type, $mid);
  221.   drupal_set_message(t('Menu item disabled.'));
  222.   drupal_goto('admin/menu');
  223. }
  224.  
  225. /**
  226.  * Menu callback; dispatch to the appropriate menu item edit function.
  227.  */
  228. function menu_edit_item($mid = 0) {
  229.   $op = $_POST['op'];
  230.   $edit = $_POST['edit'];
  231.  
  232.   $output = '';
  233.  
  234.   switch ($op) {
  235.     case t('Submit'):
  236.       menu_edit_item_validate($edit);
  237.       if (!form_get_errors()) {
  238.         menu_edit_item_save($edit);
  239.         drupal_goto('admin/menu');
  240.       }
  241.       $output .= menu_edit_item_form($edit);
  242.       break;
  243.     default:
  244.       if ($mid > 0) {
  245.         $item = db_fetch_object(db_query('SELECT * FROM {menu} WHERE mid = %d', $mid));
  246.  
  247.         $edit['mid'] = $item->mid;
  248.         $edit['pid'] = $item->pid;
  249.         $edit['path'] = $item->path;
  250.         $edit['title'] = $item->title;
  251.         $edit['description'] = $item->description;
  252.         $edit['weight'] = $item->weight;
  253.         $edit['type'] = $item->type;
  254.       }
  255.       else {
  256.         $edit['mid'] = 0; // In case a negative ID was passed in.
  257.         $edit['pid'] = 1; // default to "Navigation" menu.
  258.         $edit['type'] = MENU_CUSTOM_ITEM;
  259.       }
  260.       $output .= menu_edit_item_form($edit);
  261.   }
  262.  
  263.   print theme('page', $output);
  264. }
  265.  
  266. /**
  267.  * Present the menu item editing form.
  268.  */
  269. function menu_edit_item_form($edit) {
  270.   $menu = menu_get_menu();
  271.  
  272.   $form .= form_textfield(t('Title'), 'title', $edit['title'], 60, 128, t('The name to display for this link.'), NULL, TRUE);
  273.  
  274.   if ($edit['pid'] == 0) {
  275.     // Display a limited set of fields for menus (not items).
  276.     $form .= form_hidden('path', '');
  277.     $form .= form_hidden('pid', 0);
  278.     $form .= form_hidden('weight', 0);
  279.   }
  280.   else {
  281.     $form .= form_textfield(t('Description'), 'description', $edit['description'], 60, 128, t('The description displayed when hovering over a menu item.'));
  282.  
  283.     $path_description = t('The Drupal path this menu item links to.');
  284.     if (isset($edit['path']) && array_key_exists($edit['path'], $menu['path index']) && $menu['path index'][$edit['path']] != $edit['mid']) {
  285.       $old_mid = $menu['path index'][$edit['path']];
  286.       $old_item = $menu['items'][$old_mid];
  287.       $path_description .= "\n". t('Since a menu item "%old" already exists for "%path", this menu item is shortcut to that location.', array('%old' => l($old_item['title'], 'admin/menu/item/edit/'. $old_mid), '%path' => $edit['path']));
  288.     }
  289.  
  290.     if ($edit['type'] & MENU_CREATED_BY_ADMIN) {
  291.       $form .= form_textfield(t('Path'), 'path', $edit['path'], 60, 128, $path_description, NULL, TRUE);
  292.     }
  293.     else {
  294.       $form .= form_item(t('Path'), l($edit['path'], $edit['path']));
  295.       $form .= form_hidden('path', $edit['path']);
  296.     }
  297.  
  298.     $form .= form_checkbox(t('Expanded'), 'expanded', 1, ($edit['type'] & MENU_EXPANDED), t('If selected and this menu item has children, the menu will always appear expanded.'));
  299.  
  300.     // Generate a list of possible parents (not including this item or descendants).
  301.     $options = menu_parent_options($edit['mid']);
  302.     $form .= form_select(t('Parent item'), 'pid', $edit['pid'], $options);
  303.  
  304.     $form .= form_weight(t('Weight'), 'weight', $edit['weight'], 10, t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'));
  305.   }
  306.  
  307.   $form .= form_submit(t('Submit'));
  308.  
  309.   $form .= form_hidden('mid', $edit['mid']);
  310.  
  311.   // Always enable menu items (but not menus) when editing them.
  312.   if (!($edit['type'] & MENU_IS_ROOT)) {
  313.     $edit['type'] |= MENU_VISIBLE_IN_TREE | MENU_VISIBLE_IN_BREADCRUMB;
  314.   }
  315.  
  316.   $form .= form_hidden('type', $edit['type']);
  317.  
  318.   return form($form);
  319. }
  320.  
  321. /**
  322.  * Confirm that an edited menu item has fields properly filled in.
  323.  */
  324. function menu_edit_item_validate($edit) {
  325.   if (empty($edit['title'])) {
  326.     form_set_error('title', t('You must specify a title.'));
  327.   }
  328.  
  329.   if ($edit['pid'] != 0) {
  330.     if (empty($edit['path'])) {
  331.       form_set_error('path', t('You must specify a path.'));
  332.     }
  333.   }
  334. }
  335.  
  336. /**
  337.  * Save changes to a menu item into the database.
  338.  */
  339. function menu_edit_item_save($edit) {
  340.   $menu = menu_get_menu();
  341.  
  342.   if ($edit['expanded']) {
  343.     $edit['type'] |= MENU_EXPANDED;
  344.   }
  345.   else {
  346.     $edit['type'] &= ~MENU_EXPANDED;
  347.   }
  348.  
  349.   if ($edit['mid']) {
  350.     db_query("UPDATE {menu} SET pid = %d, path = '%s', title = '%s', description = '%s', weight = %d, type = %d WHERE mid = %d", $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN, $edit['mid']);
  351.     drupal_set_message(t('Updated menu item %title.', array('%title' => theme('placeholder', $edit['title']))));
  352.   }
  353.   else {
  354.     $mid = db_next_id('{menu}_mid');
  355.     db_query("INSERT INTO {menu} (mid, pid, path, title, description, weight, type) VALUES (%d, %d, '%s', '%s', '%s', %d, %d)", $mid, $edit['pid'], $edit['path'], $edit['title'], $edit['description'], $edit['weight'], $edit['type'] | MENU_MODIFIED_BY_ADMIN);
  356.     drupal_set_message(t('Created new menu item %title.', array('%title' => theme('placeholder', $edit['title']))));
  357.     if (array_key_exists($edit['path'], $menu['path index'])) {
  358.       $old_mid = $menu['path index'][$edit['path']];
  359.       $old_item = $menu['items'][$old_mid];
  360.       drupal_set_message(t('Since a menu item %old already exists for %path, this new menu item was created as a shortcut to that location.', array('%old' => l(theme('placeholder', $old_item['title']), 'admin/menu/item/edit/'. $old_mid, array(), NULL, NULL, FALSE, TRUE), '%path' => theme('placeholder', $edit['path']))));
  361.     }
  362.   }
  363. }
  364.  
  365. /**
  366.  * Present the menu tree, rendered along with links to edit menu items.
  367.  */
  368. function menu_overview_tree() {
  369.   $menu = menu_get_menu();
  370.   $header = array(t('Menu item'), t('Expanded'), array('data' => t('Operations'), 'colspan' => '3'));
  371.   $output = '';
  372.  
  373.   foreach ($menu['items'][0]['children'] as $mid) {
  374.     $operations = array();
  375.     if ($menu['items'][$mid]['type'] & MENU_MODIFIABLE_BY_ADMIN) {
  376.       $operations[] = l(t('edit'), 'admin/menu/item/edit/'. $mid);
  377.     }
  378.     if ($menu['items'][$mid]['type'] & MENU_CREATED_BY_ADMIN) {
  379.       $operations[] = l(t('delete'), 'admin/menu/item/delete/'. $mid);
  380.     }
  381.     $table = theme('item_list', $operations);
  382.     $table .= theme('table', $header, menu_overview_tree_rows($mid));
  383.     $output .= theme('box', $menu['items'][$mid]['title'], $table);
  384.   }
  385.   return $output;
  386. }
  387.  
  388. function menu_overview_tree_rows($pid = 0, $depth = 0) {
  389.   $menu = menu_get_menu();
  390.  
  391.   $rows = array();
  392.  
  393.   if (isset($menu['items'][$pid]) && $menu['items'][$pid]['children']) {
  394.  
  395.     usort($menu['items'][$pid]['children'], '_menu_sort');
  396.     foreach ($menu['items'][$pid]['children'] as $mid) {
  397.       // Populate the title field.
  398.       $title = '';
  399.       if ($pid == 0) {
  400.         // Top-level items are menu names, and don't have an associated path.
  401.         $title .= $menu['items'][$mid]['title'];
  402.       }
  403.       else {
  404.         $title .= l($menu['items'][$mid]['title'], $menu['items'][$mid]['path']);
  405.       }
  406.       if ($depth > 0) {
  407.         $title = '- '. $title;
  408.       }
  409.       for ($i = 1; $i < $depth; $i++) {
  410.         $title = '  '. $title;
  411.       }
  412.  
  413.       // Populate the operations field.
  414.       $operations = array();
  415.       if (!($menu['items'][$mid]['type'] & MENU_MODIFIABLE_BY_ADMIN)) {
  416.         $operations[] = array('data' => t('locked'), 'colspan' => '3', 'align' => 'center');
  417.       }
  418.       else {
  419.         if ($menu['items'][$mid]['type'] & MENU_VISIBLE_IN_TREE) {
  420.           $operations[] = array('data' => l(t('edit'), 'admin/menu/item/edit/'. $mid));
  421.           if ($menu['items'][$mid]['type'] & MENU_IS_ROOT) {
  422.             // Disabling entire menus is done from block admin page.
  423.             $operations[] = array('data' => '');
  424.           }
  425.           else {
  426.             $operations[] = array('data' => l(t('disable'), 'admin/menu/item/disable/'. $mid));
  427.           }
  428.         }
  429.         else {
  430.           $operations[] = array('data' => '');
  431.           $operations[] = array('data' => l(t('enable'), 'admin/menu/item/edit/'. $mid));
  432.         }
  433.  
  434.         if ($menu['items'][$mid]['type'] & MENU_CREATED_BY_ADMIN) {
  435.           $operations[] = array('data' => l(t('delete'), 'admin/menu/item/delete/'. $mid));
  436.         }
  437.         else if ($menu['items'][$mid]['type'] & MENU_MODIFIED_BY_ADMIN) {
  438.           $operations[] = array('data' => l(t('reset'), 'admin/menu/item/reset/'. $mid));
  439.         }
  440.         else {
  441.           $operations[] = array('data' => '');
  442.         }
  443.       }
  444.  
  445.       // Call out disabled items.
  446.       if ($menu['items'][$mid]['type'] & MENU_VISIBLE_IN_TREE) {
  447.         $class = 'menu-enabled';
  448.       }
  449.       else {
  450.         $title .= ' ('. t('disabled') .')';
  451.         $class = 'menu-disabled';
  452.       }
  453.  
  454.       if ($menu['items'][$mid]['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_VISIBLE_IN_TREE)) {
  455.         $row = array(array('data' => $title, 'class' => $class), array('data' => ($menu['items'][$mid]['children'] ? (($menu['items'][$mid]['type'] & MENU_EXPANDED) ? t('Yes') : t('No')) : ''), 'class' => $class));
  456.         foreach ($operations as $operation) {
  457.           $operation['class'] = $class;
  458.           $row[] = $operation;
  459.         }
  460.         $rows[] = $row;
  461.         $rows = array_merge($rows, menu_overview_tree_rows($mid, $depth + 1));
  462.       }
  463.       else {
  464.         // Skip items that are hidden and locked; admins will never care about them.
  465.         $rows = array_merge($rows, menu_overview_tree_rows($mid, $depth));
  466.       }
  467.     }
  468.  
  469.   }
  470.  
  471.   return $rows;
  472. }
  473.  
  474. /**
  475.  * Return a list of menu items that are valid possible parents for the
  476.  * given menu item.
  477.  */
  478. function menu_parent_options($mid, $pid = 0, $depth = 0) {
  479.   $menu = menu_get_menu();
  480.  
  481.   $options = array();
  482.  
  483.   if (isset($menu['items'][$pid]) && $menu['items'][$pid]['children']) {
  484.     usort($menu['items'][$pid]['children'], '_menu_sort');
  485.     foreach ($menu['items'][$pid]['children'] as $child) {
  486.       if ($child != $mid) {
  487.         if ($child > 0 && ($menu['items'][$child]['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT))) {
  488.           $title = ' '. $menu['items'][$child]['title'];
  489.           for ($i = 0; $i < $depth; $i++) {
  490.             $title = '--'. $title;
  491.           }
  492.           if (!($menu['items'][$child]['type'] & MENU_VISIBLE_IN_TREE)) {
  493.             $title .= ' ('. t('disabled') .')';
  494.           }
  495.           $options[$child] = $title;
  496.         }
  497.         $options += menu_parent_options($mid, $child, $depth + 1);
  498.       }
  499.     }
  500.   }
  501.  
  502.   return $options;
  503. }
  504.  
  505. ?>
  506.